package com.xhtt.common.utils;

import com.trigersoft.jaque.expression.Expression;
import com.trigersoft.jaque.expression.InvocationExpression;
import com.trigersoft.jaque.expression.LambdaExpression;
import com.trigersoft.jaque.expression.MemberExpression;

import java.io.Serializable;
import java.lang.reflect.Member;
import java.util.function.Function;

/**
 * @author wangze
 * @date 2018-05-17 15:58.
 **/
public class LambdaHelper {
    private LambdaHelper() {
    }

    private static final char UNDERLINE = '_';

    /**
     * 作为 VO 的字段解析输出,输出为下划线格式
     *
     * @param fun 函数
     * @param <T> 类型
     * @return 返回解析后的结果
     * <p>
     * Created by HCL on 2018/3/13.
     */
    public static <T> String asVOFieldUL(Property<T, ?> fun) {
        return camelToUnderline(asVOField(fun));
    }

    /**
     * @param param
     * @return
     */
    public static String camelToUnderline(String param) {
        if (param == null || "".equals(param.trim())) {
            return "";
        }
        int len = param.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c = param.charAt(i);
            if (Character.isUpperCase(c)) {
                sb.append(UNDERLINE);
                sb.append(Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 作为 VO 的字段解析输出
     *
     * @param fun 函数
     * @param <T> 类型
     * @return 返回解析后的结果
     * <p>
     * Created by HCL on 2018/3/13.
     */
    public static <T> String asVOField(Property<T, ?> fun) {
        String name = getMethodName(fun);
        if (name.startsWith("get")) {
            name = name.substring(3);
        } else if (name.startsWith("is")) {
            name = name.substring(2);
        }
        return name.substring(0, 1).toLowerCase() + name.substring(1);
    }

    /**
     * 解析方法名称
     *
     * @param fun 函数名
     * @param <T> 类型 T
     * @return 返回方法名称
     * <p>
     * Created by HCL on 2018/3/13.
     */
    public static <T> String getMethodName(Property<T, ?> fun) {
        return LambdaHelper._getMethodName(fun);
    }

    /**
     * 获取传入的 lambda 表达式名称
     *
     * @param fun 传入的函数
     * @param <T> 类型<>T</>
     * @return 返回解析后的方法名称
     * <p>
     * Created by HCL on 2018/3/13.
     */
    private static <T> String _getMethodName(Property<T, ?> fun) {
        LambdaExpression parsed = LambdaExpression.parse(fun);
        Expression body = parsed.getBody();
        Member member = ((MemberExpression) ((InvocationExpression) body).getTarget()).getMember();
        return member.getName();
    }

    /**
     * 定义属性接口，继承自 Function 接口
     *
     * @param <T>
     * @param <R> Created by HCL on 2018/3/13.
     */
    public interface Property<T, R> extends Function<T, R>, Serializable {
    }
}
